import { reactive, ref, UnwrapRef } from "vue"
import { AxiosRequestConfig } from "axios"
import { ElMessageBox, ElNotification } from 'element-plus';
import { DataOperationType } from "@/constants"
import { OperateRequests } from '@/composables/models'
import { PageInfo } from "@/composables/models"
import { request } from "@/utils/request-utils"

export function getOperations(apisRequest: OperateRequests, dataPageList: UnwrapRef<PageInfo>, pkFields: string[], operateCallback: () => void) {
    const operateType = ref(DataOperationType.default)
    const saveDrawerVisible = ref(false)
    const detailDrawerVisible = ref(false)

    const getPkParams = (item: any) => {
        const params: any = {}
        for (const pkField of pkFields) {
            params[pkField] = item[pkField]
        }
        return params
    }
    const editPk = reactive(getPkParams({}))

    const detail = (item: any) => {
        for (const pkField of pkFields) {
            editPk[pkField] = item[pkField]
        }
        detailDrawerVisible.value = true
    }

    const add = () => {
        for (const pkField of pkFields) {
            editPk[pkField] = undefined
        }
        operateType.value = DataOperationType.create
        saveDrawerVisible.value = true
    }

    const edit = (item: any, copy = false) => {
        for (const pkField of pkFields) {
            editPk[pkField] = item[pkField]
        }
        if (copy) {
            operateType.value = DataOperationType.copy
        } else {
            operateType.value = DataOperationType.update
        }
        saveDrawerVisible.value = true
    }

    const save = (detail: any) => {
        const editIndex = dataPageList.list.findIndex((item: any) => {
            for (const pkField of pkFields) {
                if (detail[pkField] !== item[pkField]) return false;
            }
            return true;
        })
        if (editIndex >= 0) {
            dataPageList.list[editIndex] = detail
        } else {
            if (operateCallback) operateCallback()
        }
    }

    const switchDeleted = (item: any) => {
        const params: any = getPkParams(item)
        const requestConfig: AxiosRequestConfig = item.deleted === 1 ? { ...apisRequest.enable, params } : { ...apisRequest.disable, params }
        request(requestConfig).then(response => {
            if (response > 0) item.deleted = item.deleted === 1 ? 0 : 1
        })
    }

    const del = (item: any) => {
        const params: any = getPkParams(item)
        const requestConfig: AxiosRequestConfig = { ...apisRequest.delete, params }
        request(requestConfig).then(response => {
            if (response > 0 && operateCallback) operateCallback()
        })
    }

    return { editPk, saveDrawerVisible, detailDrawerVisible, operateType, detail, add, del, edit, switchDeleted, save }
}

export function getSelectionWithOperations(apisRequest: OperateRequests, pkField: string, pksField: string) {

    const selectedRows = ref<any[]>([])
    const handleSelectionChange = (selection: any[]) => {
        selectedRows.value = selection
    }

    const getSelectRowKeys = (): number[] | string[] => {
        return selectedRows.value.map(item => item[pkField])
    }

    const execSelection = (operateMessage: string, getRequestConfig: () => AxiosRequestConfig, successCallback: () => void = () => undefined) => {
        return () => {
            if (selectedRows.value.length === 0) {
                ElNotification({ type: 'warning', message: `${operateMessage}列表不能为空` })
                return
            }
            ElMessageBox.confirm(`确定${operateMessage}吗？`, '', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                const requestConfig: any = getRequestConfig()
                request(requestConfig).then(response => {
                    if (response > 0) {
                        ElNotification({ type: 'success', message: `${operateMessage}成功` })
                    }
                    if (successCallback) successCallback()
                })
            }).catch(() => {
                console.log('取消操作')
            });
        }
    }

    const getRequest = (requestConfig: AxiosRequestConfig): () => AxiosRequestConfig => {
        return () => {
            const params: any = {}
            params[pksField] = getSelectRowKeys()
            return { ...requestConfig, params }
        }
    }

    const disableSelected = (callback: () => void = () => undefined) => execSelection('禁用', getRequest(apisRequest.disable), () => {
        selectedRows.value.forEach((item: any) => item.deleted = 1)
        callback && callback()
    })

    const enableSelected = (callback: () => void = () => undefined) => execSelection('启用', getRequest(apisRequest.enable), () => {
        selectedRows.value.forEach((item: any) => item.deleted = 0)
        callback && callback()
    })

    const deleteSelected = (callback: () => void = () => undefined) => execSelection('删除', getRequest(apisRequest.delete), () => {
        callback && callback()
    })

    return {
        selectedRows,
        handleSelectionChange,
        disableSelected,
        enableSelected,
        deleteSelected,
        execSelection
    }
}
